import json
from openai import OpenAI
import openai
from openai import OpenAI

client = OpenAI(api_key="sk-50a3178822814be680a60ba61fdefa78", base_url="https://api.deepseek.com")

# 导入Python标准库的json模块，用于解析和生成JSON数据。

from django.http import JsonResponse
# 从Django框架中导入JsonResponse，用于返回JSON格式的HTTP响应。
from django.shortcuts import get_object_or_404, render
from django.views.decorators.http import require_http_methods
from spark.models import User
# 导入spark应用中的User模型，用于操作用户数据表。
from rest_framework.decorators import api_view
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from .serializers import UserSerializer, GroupSerializer, SubtaskSerializer

#实现了一个简单的基于函数的视图装饰器，用于学生加入任务后保存用户数据。
from spark.models import Task, SysUser, Students, SysRole,  Group, Subtask, Application, Score, DiscussionComment, Appeal
from spark.forms import TaskForm, SysUserForm, GroupForm
from spark.serializers import UserSerializer, GroupSerializer, SubtaskSerializer, TaskSerializer
import logging
from rest_framework.permissions import IsAuthenticated
from django.db import transaction
from django.views.decorators.csrf import csrf_exempt
from celery.result import AsyncResult
from decimal import Decimal, InvalidOperation
from django.db.models import Q
from .serializers import ForumPostSerializer
from decimal import ROUND_HALF_UP
from .models import ForumPost

logger = logging.getLogger(__name__)

def validate_required_params(data, required_params):
    """
    验证请求数据中是否包含必要的参数
    :param data: 请求中的数据 (dict)
    :param required_params: 必填参数列表 (list)
    :return: (bool, missing_params) 是否验证通过，以及缺少的参数
    """
    missing_params = [param for param in required_params if not data.get(param)]
    return len(missing_params) == 0, missing_params

def save(request): #不需要理睬，但是可以当作学习参考的【增加】
    user = json.loads(request.body)
    _id = user.get('id')
    if _id is None:
        User.objects.create(**user)
    else:
        User.objects.filter(id=_id).update(**user)
    return JsonResponse(None, safe=False)

def remove(request, _id):  #不需要理睬，但是可以当作学习参考的【删除】
    User.objects.get(pk=_id).delete()
    return JsonResponse(None, safe=False)
def search(request): #不需要理睬，但是可以当作学习参考的【查找】
    body = json.loads(request.body)
    query = {
        f'{key}__icontains': body.get(key)
        for key in body.keys()
        if body.get(key)
    }
    query_set = User.objects.filter(**query).values()
    return JsonResponse(list(query_set), safe=False)

# 注册功能
@require_http_methods(["POST"])
def register(request):
    try:
        data = json.loads(request.body)
        username = data.get("username")
        password = data.get("password")
        email = data.get("email")  # 假设注册需要邮箱字段

        # 检查必填字段
        if not all([username, password, email]):
            return JsonResponse({"status": "error", "message": "缺少必要字段"}, status=400)

        # 检查用户名是否已存在
        if SysUser.objects.filter(username=username).exists():
            return JsonResponse({"status": "error", "message": "用户名已存在"}, status=400)

        # 创建新用户
        SysUser.objects.create(
            username=username,
            password=password,
            email=email,
            status=1,  # 默认用户状态设置为可用
        )
        return JsonResponse({"status": "success", "message": "注册成功"})
    except Exception as e:
        print(f"注册失败: {e}")
        return JsonResponse({"status": "error", "message": "服务器内部错误"}, status=500)


# 登录功能
@require_http_methods(["POST"])
def login(request):
    try:
        data = json.loads(request.body)
        username = data.get("username")
        password = data.get("password")

        # 检查必填字段
        if not all([username, password]):
            return JsonResponse({"status": "error", "message": "缺少必要字段"}, status=400)

        # 查询用户
        user = SysUser.objects.filter(username=username, password=password, status=1).first()
        print(f"登录查询条件: username={username}, password={password}")
        print(f"查询结果: {user}")

        if user:
            return JsonResponse({
                "status": "success",
                "user_id": user.user_id,
                "username": user.username,
                "role": "teacher" if user.role == "teacher" else "student",
                "message": "登录成功"
            })
        else:
            return JsonResponse({"status": "error", "message": "用户名或密码错误"}, status=400)

    except Exception as e:
        print(f"登录失败: {e}")
        return JsonResponse({"status": "error", "message": "服务器内部错误"}, status=500)

# 创建任务
@require_http_methods(["POST"])
def create_task(request):
    try:
        print("请求的 POST 数据:", request.POST)  # 打印接收到的 POST 数据
        print("请求的 FILES 数据:", request.FILES)  # 打印接收到的文件数据（如果有）

        # 从请求中获取字段
        title = request.POST.get("title")
        description = request.POST.get("description")
        min_group_size = request.POST.get("min_group_size")
        max_group_size = request.POST.get("max_group_size")
        deadline = request.POST.get("deadline")
        scoring_criteria = request.POST.get("scoring_criteria")
        teacher_id = request.POST.get("teacher_id")  # 确认是否正确传递教师 ID
        sample = request.FILES.get("sample")  # 获取上传的文件

        # 检查必要字段是否存在
        required_fields = [title, description, min_group_size, max_group_size, deadline, scoring_criteria, teacher_id]
        if not all(required_fields):
            print("缺少必要字段")
            return JsonResponse({"status": "error", "message": "缺少必要字段"}, status=400)

        # 获取教师对象
        teacher = SysUser.objects.filter(user_id=teacher_id).first()
        if not teacher:
            print("教师不存在")
            return JsonResponse({"status": "error", "message": "教师不存在"}, status=404)

        # 创建任务
        task = Task.objects.create(
            title=title,
            description=description,
            min_group_size=int(min_group_size),
            max_group_size=int(max_group_size),
            deadline=deadline,
            scoring_criteria=scoring_criteria,
            sample=sample,
            teacher=teacher  # 关联教师对象
        )

        # 返回任务创建成功信息
        return JsonResponse({"status": "success", "message": "任务创建成功", "task_id": task.id})
    except Exception as e:
        print(f"任务创建失败: {e}")
        return JsonResponse({"status": "error", "message": "服务器内部错误: " + str(e)}, status=500)

#教师部分获取任务列表，并显示
@require_http_methods(["GET"])
def teacher_task_list(request):
    try:
        teacher_id = request.GET.get("teacher_id")
        if not teacher_id:
            return JsonResponse({"status": "error", "message": "缺少教师 ID"}, status=400)

        tasks = Task.objects.filter(teacher_id=teacher_id).values(
            "id", "title", "description", "min_group_size", "max_group_size",
            "deadline", "scoring_criteria", "status"
        )
        return JsonResponse({"status": "success", "data": list(tasks)})
    except Exception as e:
        print(f"获取任务失败: {e}")
        return JsonResponse({"status": "error", "message": "服务器内部错误"}, status=500)

#学生部分获取总任务列表，并显示
@require_http_methods(["GET"])
def student_task_list(request):
    try:
        tasks = Task.objects.all().values(
            "id", "title", "description", "min_group_size", "max_group_size",
            "deadline", "scoring_criteria", "status"
        )
        return JsonResponse({"status": "success", "data": list(tasks)})
    except Exception as e:
        print(f"获取任务失败: {e}")
        return JsonResponse({"status": "error", "message": "服务器内部错误"}, status=500)

#学生加入任务
@api_view(['POST'])
def join_task(request, task_id):
    student_username = request.data.get('student_username')

    # 检查必要字段
    if not student_username:
        return Response({"status": "error", "message": "缺少必要字段"}, status=400)

    try:
        logger.debug(f"查找任务: task_id={task_id}")
        task = Task.objects.get(id=task_id)  # 查找已有的 Task 实例
        logger.debug(f"查找学生: student_username={student_username}")
        student = SysUser.objects.get(username=student_username)  # 查找学生

        logger.debug(f"将学生加入到任务: task_id={task_id}, student_username={student_username}")
        # 检查学生是否已经加入该任务
        if Students.objects.filter(task=task, user=student).exists():
            return Response({"status": "already_joined", "message": "该学生已加入此任务"}, status=200)
        # 将学生加入到任务的 Students 表中
        Students.objects.create(task=task, user=student)
        task.students_number += 1
        task.save()
        return Response({"status": "success", "message": "成功加入任务"})

    except SysUser.DoesNotExist:
        logger.error(f"学生不存在: student_username={student_username}")
        return Response({"status": "error", "message": "学生不存在"}, status=404)
    except Exception as e:
        logger.error(f"服务器内部错误: {e}")
        return Response({"status": "error", "message": str(e)}, status=500)

#获取任务的学生列表
@require_http_methods(["GET"])
def task_students(request, task_id):
    try:
        task = Task.objects.get(id=task_id)
        students = Students.objects.filter(task=task).select_related('user')
        student_usernames = [student.user.username for student in students]
        return JsonResponse({"status": "success", "data": student_usernames})
    except Task.DoesNotExist:
        return JsonResponse({"status": "error", "message": "任务不存在"}, status=404)
    except Exception as e:
        return JsonResponse({"status": "error", "message": str(e)}, status=500)

#通过用户名查询用户信息
@require_http_methods(["GET"])
def get_user_by_username(request, username):
    try:
        user = SysUser.objects.get(username=username)
        user_data = {
            "user_id": user.user_id,
            "username": user.username,
            "nickname": user.nickname,
            "email": user.email,
        }
        return JsonResponse({"status": "success", "data": user_data})
    except SysUser.DoesNotExist:
        return JsonResponse({"status": "error", "message": "用户不存在"}, status=404)
    except Exception as e:
        return JsonResponse({"status": "error", "message": str(e)}, status=500)

@api_view(['POST'])
def update_task_status(request, task_id):
    """
    更新任务状态
    """
    # 获取请求数据中的状态
    new_status = request.data.get('status', None)

    if not new_status:
        return Response({"status": "error", "message": "缺少状态信息"}, status=400)

    # 获取任务对象
    task = get_object_or_404(Task, id=task_id)

    # 更新任务状态
    task.status = new_status
    task.save()

    return Response({"status": "success", "message": f"任务状态更新为 {new_status}"})

#获取任务的学生列表
@require_http_methods(["GET"])
def task_students(request, task_id):
    try:
        task = Task.objects.get(id=task_id)
        students = Students.objects.filter(task=task).select_related('user')
        student_usernames = [student.user.username for student in students]
        return JsonResponse({"status": "success", "data": student_usernames})
    except Task.DoesNotExist:
        return JsonResponse({"status": "error", "message": "任务不存在"}, status=404)
    except Exception as e:
        return JsonResponse({"status": "error", "message": str(e)}, status=500)

#通过用户名查询用户信息
@require_http_methods(["GET"])
def get_user_by_username(request, username):
    try:
        user = SysUser.objects.get(username=username)
        user_data = {
            "user_id": user.user_id,
            "username": user.username,
            "nickname": user.nickname,
            "email": user.email,
        }
        return JsonResponse({"status": "success", "data": user_data})
    except SysUser.DoesNotExist:
        return JsonResponse({"status": "error", "message": "用户不存在"}, status=404)
    except Exception as e:
        return JsonResponse({"status": "error", "message": str(e)}, status=500)

#老师选中任务的组长
@api_view(['POST'])
def set_group_leaders(request, task_id):
    """
    设置某个任务的小组组长
    """
    leaders = request.data.get('leaders', [])
    print(f"传向后端的组长名单: {leaders}")

    if not leaders:
        return Response({"status": "error", "message": "缺少组长名单"}, status=400)

    # 获取任务对象
    task = get_object_or_404(Task, id=task_id)
    print(f"找到的任务: {task}")

    # 获取所有组长的 user_id 列表
    leader_user_ids = []
    for leader_username in leaders:
        try:
            leader = get_object_or_404(SysUser, username=leader_username)
            leader_user_ids.append(leader.user_id)
            print(f"组长 {leader_username} 对应的 user_id: {leader.user_id}")
        except SysUser.DoesNotExist:
            print(f"用户 {leader_username} 未找到")
            return Response({"status": "error", "message": f"组长 {leader_username} 未找到"}, status=404)

    try:
        # 使用事务保证原子性
        with transaction.atomic():
            # 获取当前任务已有的组长的 user_id 列表
            current_leaders = task.leaders.all().values_list('user_id', flat=True)
            print(f"当前任务的组长 IDs: {current_leaders}")

            # 找出需要插入的新组长（那些不存在于现有记录中的）
            new_leaders = [user_id for user_id in leader_user_ids if user_id not in current_leaders]
            print(f"需要添加的组长 IDs: {new_leaders}")

            if not new_leaders:
                return Response({"status": "success", "message": "所有组长已存在，无需添加"})

            # 检查组长人数是否超过最大组长人数
            if len(current_leaders) + len(new_leaders) > task.max_group_size:
                return Response({"status": "error", "message": "组长人数超过最大限制"})

            # 将新组长添加到任务的 leaders 字段中
            for user_id in new_leaders:
                leader = SysUser.objects.get(user_id=user_id)
                task.leaders.add(leader)
                #    这里为了简单，直接创建新的小组
                group = Group.objects.create(
                    group_name=leader.username,  # 小组名设为组长用户名
                    leader_id=leader,  # leader_id 指向组长
                    group_task=task  # 关联到当前任务
                )
                # 3) 将组长加入该小组的 members 中
                group.members.add(leader)
                group.save()

            # 更新任务状态为 grouping_up
            task.status = 'grouping_up'
            task.save()

        return Response({"status": "success", "message": "组长设置成功"})
    except Exception as e:
        print(f"出现错误: {str(e)}")
        return Response({"status": "error", "message": str(e)}, status=500)


@api_view(['GET'])
def get_task_leaders(request, task_id):
    """
    获取某个任务的组长列表
    """
    task = get_object_or_404(Task, id=task_id)
    # 获取任务中的所有组长，并构造简单的数据结构返回
    leaders = task.leaders.all().values('user_id', 'username', 'avatar')
    return Response({"status": "success", "data": list(leaders)})

@csrf_exempt
def deepseek_analyze_meeting_notes(request):
    # openai.api_base = "https://api.deepseek.com"
    # openai.api_base = "sk-50a3178822814be680a60ba61fdefa78"
    """
        接收会议记录文本，构造提示词后调用 Deepseek API 生成会议摘要和发言人贡献分析，
        最后将结果返回给前端。
        """
    if request.method != "POST":
        return JsonResponse({"error": "Invalid request method"}, status=405)

    try:
        data = json.loads(request.body)
    except Exception as e:
        return JsonResponse({"error": "Invalid JSON", "details": str(e)}, status=400)

    meeting_text = data.get("text", "")
    group_id = data.get("group_id")
    task_id = data.get("task_id")
    sysuser_id = data.get("sysuser_id")

    if not meeting_text or not group_id or not task_id or not sysuser_id:
        return JsonResponse({"error": "Missing required parameters"}, status=400)

    logger.info(
        f"Received meeting text: {meeting_text[:50]}..., group_id: {group_id}, task_id: {task_id}, sysuser_id: {sysuser_id}")

    # 构造提示词：要求 DeepSeek 输出 JSON 格式，其中 contributions 数组中包含“姓名”和“综合评分”等字段
    prompt = f"""
    假设你是一名绩效评估师，请根据以下会议记录生成会议摘要和各发言人的贡献评分(0-100)，请严格按以下 JSON 格式输出，不要添加额外文字：
    {{
      "summary": "会议摘要内容",
      "contributions": [
        {{
          "姓名": "发言人姓名",
          "综合评分": 75,
          "内容关联度": 80,
          "参与积极性": 90,
          "沟通表达能力": 80,
          "会议进程推动": 75,
          "想法创新性": 67,
          "综合评价": "文字评价，请解释每一项的给分理由"
        }}
      ]
    }}
    会议记录如下：
    {meeting_text}
        """
    try:
        logger.info("开始调用 DeepSeek 分析会议记录...")
        completion = client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "You are a fair performance evaluator."},
                {"role": "user", "content": prompt},
            ],
            stream=False
        )
        analysis_raw = completion.choices[0].message.content
        # 去除可能的多余标记
        analysis_str = analysis_raw.replace("```json", "").replace("```", "").strip()
        logger.info(f"DeepSeek 返回原始结果: {analysis_str}")
        #print(f"DeepSeek 返回原始结果: {analysis_str}")
        # 尝试解析 JSON
        analysis_json = json.loads(analysis_str)

        # 这里假设 DeepSeek 返回的 JSON 中 contributions 数组至少有一项，
        # 并且“综合评分”字段存在。可以根据需要遍历多个贡献者，这里只取第一项
        contributions = analysis_json.get("contributions", [])
        if not contributions:
            return JsonResponse({"error": "No contributions found in analysis"}, status=500)

        first_contrib = contributions[0]
        # 提取综合评分（假设为浮点数）
        comprehensive_score = first_contrib.get("综合评分")
        contributor_name = first_contrib.get("姓名")
        if comprehensive_score is None:
            return JsonResponse({"error": "综合评分 not found in analysis"}, status=500)

        # 根据前端传来的 group_id, task_id, sysuser_id 获取对应的对象
        try:
            group_obj = Group.objects.get(pk=group_id)
            task_obj = Task.objects.get(pk=task_id)
            sysuser_obj = SysUser.objects.get(pk=sysuser_id)
        except Exception as e:
            return JsonResponse({"error": "Invalid group/task/sysuser id", "details": str(e)}, status=400)

        # 创建 Score 记录：这里只存储 negotiate 分数为综合评分，其它评分字段设为0或默认值，raters为空
        score = Score.objects.create(
            quality=0,
            engagement=comprehensive_score,
            negotiate=comprehensive_score,
            on_time=100,
            rematch_willingness=80,
            total=0,
        )
        # 建立关联：假设一个评分记录对应单个学生、单个任务和单个小组，使用 add() 方法
        score.sysusers.add(sysuser_obj)
        score.tasks.add(task_obj)
        score.groups.add(group_obj)
        # raters 保持为空
        score.save()

        logger.info(f"Score record created: {score} with negotiate = {score.negotiate}")

        return JsonResponse({
            "analysis": analysis_json,
            "score_created": True,
            "score_id": score.id,
            "message": f"Score created for {sysuser_obj.username} with negotiate score {comprehensive_score}"
        }, status=200)

    except Exception as e:
        logger.exception("DeepSeek 分析或 Score 创建出错:")
        return JsonResponse({
            "error": "DeepSeek 分析出错",
            "details": str(e)
        }, status=500)

#组长获取申请信息数量
@api_view(['GET'])
def get_applicant_count(request, task_id):
    leader_id = request.query_params.get('leader_id')
    if not leader_id:
        return Response({"error": "缺少 leader_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

    try:
        count = Application.objects.filter(task_id=task_id, leader_id=leader_id, is_read=False).count()
        return Response({"applicant_count": count}, status=status.HTTP_200_OK)
    except Exception as e:
        return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

#组长查看已读状态
@api_view(['POST'])
def mark_applications_as_read(request):
    leader_id = request.data.get('user_id')
    task_id = request.data.get('task_id')
    if leader_id and task_id:
        # 打印查询条件
        print(f"查询条件: leader_id={leader_id}, task_id={task_id}")

        # 打印查询结果
        applications = Application.objects.filter(leader_id=leader_id, task_id=task_id, is_read=False)
        print(f"未读申请数量: {applications.count()}")
        for app in applications:
            print(f"未读申请: {app}")

        # 更新操作
        applications.update(is_read=True)

        # 打印更新后的结果
        updated_applications = Application.objects.filter(leader_id=leader_id, task_id=task_id, is_read=True)
        print(f"已读申请数量: {updated_applications.count()}")
        for app in updated_applications:
            print(f"已读申请: {app}")

        return Response({'status': 'success'})
    return Response({'status': 'error', 'message': '缺少必要参数'}, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET'])
def get_application_details(request):
    """
    根据传入的 task_id 和 leader_id 返回该组所有申请详情。
    示例请求：GET /api/application-details/?task_id=7&leader_id=5
    返回示例：
    [
      {
        "application_id": 12,
        "application_text": "我的申请理由……",
        "created_at": "2025-03-01T12:34:56Z",
        "applicant": {
            "user_id": 101,
            "username": "张三",
            "ability": 80,
            "enthusiasm": 85,
            "communication": 90,
            "popularity": 70,
            "credit": 95,
            "times": 3
        },
        "is_read": false
      },
      ...
    ]
    """
    task_id = request.query_params.get("task_id")
    leader_id = request.query_params.get("leader_id")
    if not task_id or not leader_id:
        return Response({"error": "缺少 task_id 或 leader_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

    applications = Application.objects.filter(task_id=task_id, leader_id=leader_id)

    # 构造返回数据
    app_list = []
    for app in applications:
        applicant = app.user  # 申请人
        app_list.append({
            "application_id": app.id,
            "application_text": app.application_text,
            "created_at": app.created_at,
            "is_read": app.is_read,
            "applicant": {
                "user_id": applicant.user_id,
                "username": applicant.username,
                "ability": applicant.ability,
                "enthusiasm": applicant.enthusiasm,
                "communication": applicant.communication,
                "popularity": applicant.popularity,
                "credit": applicant.credit,
                "times": applicant.times,
            }
        })
    return Response(app_list, status=status.HTTP_200_OK)


@api_view(['POST'])
def accept_application(request):
    """
    组长同意某个组员的申请：
    前端需要传入参数：
      - application_id：申请记录 ID
    操作：
      1. 根据 application_id 获取申请记录
      2. 将该申请人加入对应 Group 的成员中
      3. 更新申请记录状态（这里设置 is_read 为 True，可扩展为“accepted”状态）
    """
    application_id = request.data.get("application_id")
    print(f"接收到的申请 ID: {application_id}")
    if not application_id:
        return Response({"error": "缺少 application_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

    # 获取申请记录
    application = get_object_or_404(Application, id=application_id)

    # 获取对应的小组，假设申请记录对应的任务和组长确定唯一一个小组
    try:
        group = Group.objects.get(group_task=application.task, leader_id=application.leader.user_id)
    except Group.DoesNotExist:
        return Response({"error": "对应的小组不存在"}, status=status.HTTP_404_NOT_FOUND)

    # 将申请人加入小组成员（若未加入）
    if not group.members.filter(user_id=application.user.user_id).exists():
        group.members.add(application.user)
        group.save()

    # 更新申请记录状态，标记为已同意（这里简单使用 is_read 字段标记，也可以新增状态字段）
    application.is_read = True
    application.save()

    return Response({
        "message": "申请已同意，申请人已加入小组",
        "application_id": application.id
    }, status=status.HTTP_200_OK)

@api_view(['POST'])
def check_and_update_task_statuses(request):
    """
    教师登录后调用此接口，对该教师名下所有任务的状态进行审查并更新：
      1. 如果 sum(group.members.count()) == task.students_number => task.status = 'task_division'
      2. 如果 ReferencePosition.objects.filter(task=task).count() == task.students_number => task.status = 'working'
      3. 如果 Score.objects.filter(tasks=task).count() == task.students_number => task.status = 'scoring'
    """
    teacher_id = request.data.get("teacher_id")
    if not teacher_id:
        return Response({"error": "缺少 teacher_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

    tasks = Task.objects.filter(teacher__user_id=teacher_id)
    updated_tasks = []

    for task in tasks:
        # 计算该任务的小组成员总数
        total_members = 0
        for g in task.groups.all():  # groups 由 related_name="groups"
            total_members += g.members.count()

        # 检查并更新状态的优先顺序可根据实际业务逻辑决定
        # 以下示例按给出的顺序依次检查
        old_status = task.status

        # 1. 如果小组成员总数 == task.students_number => status = 'task_division'
        if total_members == task.students_number and task.status != 'finished':
            task.status = 'task_division'

        # 2. 如果 ReferencePosition 数量 == task.students_number => status = 'working'
        ref_count = ReferencePosition.objects.filter(task=task).count()
        if ref_count == task.students_number and task.status != 'finished':
            task.status = 'working'

        # 3. 如果 Score 记录数 == task.students_number => status = 'scoring'
        # 假设 Score 模型中有 tasks 多对多或外键，如果多对多，用 filter(tasks=task).distinct() 统计
        score_count = Score.objects.filter(tasks=task).count()
        if score_count == task.students_number and task.status != 'finished':
            task.status = 'scoring'

        # 如果状态有变化就保存
        if task.status != old_status:
            task.save()
            updated_tasks.append({
                "task_id": task.id,
                "old_status": old_status,
                "new_status": task.status
            })

    return Response({
        "message": "任务状态审查完成",
        "updated_tasks": updated_tasks
    }, status=status.HTTP_200_OK)

class GetLeaderDetailsView(APIView):
    """
    根据 leader_id 获取组长的详细信息和能力字段
    示例请求：GET /api/leader-details/?leader_id=101
    返回示例：
    {
      "user_id": 101,
      "username": "张三",
      "avatar": "avatars/xxx.jpg",
      "ability": 80,
      "enthusiasm": 85,
      "communication": 90,
      "popularity": 70,
      "credit": 95,
      "times": 3
    }
    """

    def get(self, request, *args, **kwargs):
        leader_id = request.query_params.get("leader_id")
        if not leader_id:
            return Response({"error": "缺少 leader_id 参数"}, status=status.HTTP_400_BAD_REQUEST)
        leader = get_object_or_404(SysUser, user_id=leader_id)
        data = {
            "user_id": leader.user_id,
            "username": leader.username,
            "avatar": leader.avatar.url if leader.avatar else "",
            "ability": leader.ability,
            "enthusiasm": leader.enthusiasm,
            "communication": leader.communication,
            "popularity": leader.popularity,
            "credit": leader.credit,
            "times": leader.times,
        }
        return Response(data, status=status.HTTP_200_OK)


# 2. 组员提交组队申请（SubmitApplicationView）
class SubmitApplicationView(APIView):
    """
    组员向指定组长提交申请接口
    前端传入参数：
      - task_id: 任务ID
      - leader_id: 目标组长的ID
      - applicant_id: 当前申请人的ID
      - application_text: 申请内容
    处理逻辑：
      1. 根据 task_id、leader_id 和 applicant_id 创建一条 Application 记录
      2. 返回操作结果
    """

    def post(self, request, *args, **kwargs):
        task_id = request.data.get("task_id")
        leader_id = request.data.get("leader_id")
        applicant_id = request.data.get("applicant_id")
        application_text = request.data.get("application_text")

        if not (task_id and leader_id and applicant_id and application_text):
            return Response({"error": "缺少必要参数"}, status=status.HTTP_400_BAD_REQUEST)

        # 检查申请人是否已经申请或已经加入小组（可根据实际业务需求扩展）
        # 此处直接创建申请记录
        try:
            # 获取任务和相关用户对象（假设任务存在）
            task = get_object_or_404(Task, id=task_id)
            leader = get_object_or_404(SysUser, user_id=leader_id)
            applicant = get_object_or_404(SysUser, user_id=applicant_id)

            # 创建申请记录
            application = Application.objects.create(
                task=task,
                leader=leader,
                user=applicant,
                application_text=application_text,
            )
            return Response({
                "message": "申请提交成功",
                "application_id": application.id
            }, status=status.HTTP_201_CREATED)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from spark.models import SysUser
from .serializers import UserSerializer  # 确保导入了序列化器

logger = logging.getLogger(__name__)

class UserProfileView(APIView):
    def get(self, request):
        user_id = request.query_params.get('user_id')

        if not user_id:
            logger.error("Missing user_id")
            return Response({'error': 'Missing user_id'}, status=400)

        try:
            # 强制转换为整数并查询用户
            user_id = int(user_id)
            user = SysUser.objects.get(user_id=user_id)
            serializer = UserSerializer(user)
            return Response(serializer.data)

        except ValueError:
            logger.error(f"Invalid user_id: {user_id}")
            return Response({'error': 'Invalid user_id'}, status=400)
        except SysUser.DoesNotExist:
            logger.error(f"User {user_id} not found")
            return Response({'error': 'User not found'}, status=404)
        except Exception as e:
            logger.error(f"Error fetching user profile: {str(e)}")
            return Response({'error': str(e)}, status=500)


class UserJoinedTasksView(APIView):
    def get(self, request):
        user_id = request.query_params.get('user_id')
        if not user_id:
            return Response({"error": "Missing user_id"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 使用 prefetch_related 来优化查询
            tasks = Students.objects.filter(user_id=user_id).select_related('task')
            task_data = [{
                'task_id': task.task.id,
                'title': task.task.title,
                'status': task.task.status,
                'course': task.task.teacher_id,  # 确保 Task 模型有 course 字段
            } for task in tasks]

            return Response(task_data)

        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



#class SubtaskViewSet(viewsets.ModelViewSet):
#    serializer_class = SubtaskSerializer
#    permission_classes = [IsAuthenticated]

#    def get_queryset(self):
        # 获取当前用户所在的所有小组成员
    #    user_groups = GroupMember.objects.filter(user_id=self.request.user.id)
        # 获取当前用户所在小组的所有子任务
    #    return Subtask.objects.filter(group_id__in=user_groups.values('group_id'))

#    def perform_create(self, serializer):
        # 获取当前用户的 ID
#        user = self.request.user
        # 获取当前用户所在的组（假设用户只有一个组）
#        group_member = GroupMember.objects.get(user_id=user.id)
#        group = group_member.group
        # 在创建子任务时，自动关联创建者和小组
#        serializer.save(created_by=user, group_id=group)

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Task, SysUser

class TaskDetailView(APIView):
    def get(self, request, task_id):
        user_id = request.query_params.get('user_id')
        print("user_id:", user_id)
        try:
            task = Task.objects.get(id=task_id)#or id?
            # 可以根据 user_id 返回用户与任务相关的详细数据
            # 这里假设返回任务和用户的基本信息
            print(task.id)
            user_data = SysUser.objects.get(user_id=user_id)
            return Response({
                'task': {'title': task.title, 'description': task.description, 'deadline': task.deadline, 'scoring_criteria': task.scoring_criteria, 'students_number': task.students_number, 'status': task.status},
                'user': {'username': user_data.username, 'email': user_data.email},
                'user_id': user_id
            }, status=status.HTTP_200_OK)
        except Task.DoesNotExist:
            return Response({'error': 'Task not found'}, status=status.HTTP_404_NOT_FOUND)
        except SysUser.DoesNotExist:
            return Response({'error': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

class GetGroupMembersView(APIView):
    def get(self, request):
        user_id = request.query_params.get('user_id')

        if not user_id:
            return Response({"error": "User ID is required"}, status=400)

        try:
            # 查找当前用户的组
            user = SysUser.objects.get(user_id=user_id)
            group_membership = GroupMember.objects.filter(user_id=user.id)

            if not group_membership.exists():
                return Response({"error": "No group found for this user"}, status=404)

            group_id = group_membership.first().group_id
            # 查找所有属于该 group_id 的成员
            members = SysUser.objects.filter(groupmember__group_id=group_id)
            members_data = SysUserSerializer(members, many=True).data

            return Response(members_data)

        except SysUser.DoesNotExist:
            return Response({"error": "User not found"}, status=404)
        except Exception as e:
            return Response({"error": str(e)}, status=500)


class GetUserGroupView(APIView):
    """
    根据 user_id 和 task_id 查询用户所在小组的信息
    """
    def get(self, request):
        user_id = request.query_params.get('user_id')
        task_id = request.query_params.get('task_id')
        if not user_id or not task_id:
            return Response({"error": "缺少必要参数 user_id 或 task_id"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 根据 task_id 和成员关联查询，判断该用户是否已经加入该任务的小组
            group = Group.objects.filter(group_task_id=task_id, members__user_id=user_id).first()
            if group:
                data = {
                    "group_id": group.id,
                    "group_name": group.group_name,
                    "leader": {
                    "user_id": group.leader_id.user_id,
                    "username": group.leader_id.username
                    }
                }
                return Response(data, status=status.HTTP_200_OK)
            else:
                return Response({"message": "该用户尚未加入该任务的小组"}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class GetSubtasksByGroupView(APIView):
    """
       根据 group_id 获取子任务列表
       """

    def get(self, request, group_id):
        try:
            # 查询该组下的所有子任务
            subtasks = Subtask.objects.filter(group_id=group_id)
            subtasks_data = SubtaskSerializer(subtasks, many=True).data
            return Response(subtasks_data, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from .models import Subtask, Group, SysUser
from .serializers import SubtaskSerializer

class SubtaskViewSet(viewsets.ModelViewSet):
    serializer_class = SubtaskSerializer
    #permission_classes = [IsAuthenticated]
    def get_queryset(self):
        group_id = self.request.query_params.get('group_id')
        if group_id:
            return Subtask.objects.filter(group_id=group_id)
        return Subtask.objects.all()

    def perform_create(self, serializer):
        # 获取当前用户（如果未认证，使用第一个用户，仅供开发测试）
        #user = self.request.user if self.request.user.is_authenticated else SysUser.objects.first()
        create_by = self.request.data.get('user_id')
        # 从请求中获取必要的字段
        group_id = self.request.data.get('group_id')
        task_id = self.request.data.get('task')
        assigned_to_id = self.request.data.get('assigned_to')
        description = self.request.data.get('description')
        start_date = self.request.data.get('start_date')
        end_date = self.request.data.get('end_date')
        status_value = self.request.data.get('status', 'in_progress')

        # 检查必须字段
        if not group_id:
            raise ValidationError({"group_id": "This field is required."})
        if not task_id:
            raise ValidationError({"task": "This field is required."})

        try:
            group_instance = Group.objects.get(id=group_id)
        except Group.DoesNotExist:
            raise ValidationError({"group_id": "Invalid group id."})

        try:
            task_instance = Task.objects.get(id=task_id)
        except Task.DoesNotExist:
            raise ValidationError({"task": "Invalid task id."})

        try:
            assigned_to_instance = SysUser.objects.get(user_id=assigned_to_id) if assigned_to_id else None
        except SysUser.DoesNotExist:
            raise ValidationError({"assigned_to": "Invalid assigned_to id."})

        try:
            create_by_instance = SysUser.objects.get(user_id=create_by) if create_by else None
        except SysUser.DoesNotExist:
            raise ValidationError({"create_by": "Invalid create_by id."})

        # 直接创建 Subtask 对象并保存
        subtask = Subtask.objects.create(
            task=task_instance,
            created_by=create_by_instance,
            assigned_to=assigned_to_instance,
            group_id=group_instance,
            status=status_value,
            start_date=start_date,
            end_date=end_date,
            description=description
        )
        # 如果需要，你可以将 subtask 赋值给 serializer.instance
        serializer.instance = subtask


class AllUsersView(APIView):
    """
    返回所有用户列表的视图
    """
    def get(self, request):
        try:
            users = SysUser.objects.all()
            serializer = UserSerializer(users, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Subtask
import requests
from django.utils import timezone

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.utils import timezone
from django.shortcuts import get_object_or_404
from celery.result import AsyncResult

from spark.models import Subtask
from spark.tasks import process_deepseek_task  # 导入上面定义的 Celery 任务


class SubmitTaskFileView(APIView):
    """
    前端提交任务文件后，先更新子任务基本信息，
    然后将 DeepSeek 分析任务交给 Celery 异步执行，
    返回 job_id 给前端供后续轮询查询。
    """

    def post(self, request, *args, **kwargs):
        task_id = request.data.get("task_id")
        file_content = request.data.get("fileContent", "")
        task_description = request.data.get("taskDescription", "")
        user_id = request.data.get("user_id")

        # 获取对应的 Subtask 记录
        subtask = get_object_or_404(Subtask, pk=task_id)
        subtask.submitted_time = timezone.now()

        now_date = timezone.now().date()
        if now_date > subtask.end_date:
            subtask.status = 'late'
        else:
            subtask.status = 'on_time'
        subtask.save()

        # 异步执行 DeepSeek 分析任务，并传入必要参数
        job = process_deepseek_task.delay(subtask.id, task_description, file_content)

        return Response({"job_id": job.id}, status=status.HTTP_202_ACCEPTED)


class SubmitTaskFileStatusView(APIView):
    """
    前端通过 job_id 查询 DeepSeek 异步任务状态和返回结果，
    当任务完成时返回审核评论和最终子任务状态。
    """

    def get(self, request, *args, **kwargs):
        job_id = request.query_params.get("job_id")
        if not job_id:
            return Response({"error": "缺少 job_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

        result = AsyncResult(job_id)
        if result.state == 'SUCCESS':
            analysis = result.get()  # 获取 DeepSeek 分析结果
            print("DeepSeek 分析结果:", analysis)
            return Response({
                "state": result.state,
                "review_result": analysis
            }, status=status.HTTP_200_OK)
        elif result.state in ['PENDING', 'STARTED']:
            return Response({"state": result.state}, status=status.HTTP_202_ACCEPTED)
        else:
            return Response({
                "state": result.state,
                "error": str(result.result)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

from django.core.mail import send_mail
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class RemindTaskView(APIView):
    """
    发送任务未完成提醒
    """
    def post(self, request):
        task_id = request.data.get('task_id')
        user_id = request.data.get('user_id')

        # 获取任务和成员信息
        task = Subtask.objects.get(id=task_id)
        user = SysUser.objects.get(user_id=user_id)

        # 发送提醒邮件
        subject = f"任务提醒: {task.task.title}"
        message = f"你好，\n\n你的任务 {task.task.title} 尚未完成，请尽快提交。\n\n任务详情:\n开始日期: {task.start_date}\n结束日期: {task.end_date}\n\n谢谢！"
        from_email = settings.EMAIL_HOST_USER

        send_mail(subject, message, from_email, [user.email])

        return Response({"message": "提醒已发送"}, status=status.HTTP_200_OK)


class GetSubtaskReviewView(APIView):
    """
    用于查看子任务的评阅结果（comments）。
    前端可以传入子任务 ID 来获取评阅结果。
    """

    def get(self, request, *args, **kwargs):
        # 假设子任务ID通过查询参数传入，例如 ?subtask_id=2
        subtask_id = request.query_params.get("task_id")
        if not subtask_id:
            return Response({"error": "缺少 subtask_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

        subtask = get_object_or_404(Subtask, pk=subtask_id)
        data = {
            "subtask_id": subtask.id,
            "comments": subtask.comments,
            "status": subtask.status
        }
        return Response(data, status=status.HTTP_200_OK)

from django.http import JsonResponse
from spark.models import Score, SysUser, Group, Task
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Prefetch

@csrf_exempt
def get_group_negotiate_scores(request):
    """
    获取指定任务和小组的所有成员的评分数据（negotiate 分数）
    """
    if request.method != "GET":
        return JsonResponse({"error": "Invalid request method"}, status=405)

    task_id = request.GET.get("task_id")
    group_id = request.GET.get("group_id")

    if not task_id or not group_id:
        return JsonResponse({"error": "Missing required parameters"}, status=400)

    try:
        group = Group.objects.get(id=group_id)
        task = Task.objects.get(id=task_id)

        # 获取小组成员
        members = group.members.all()

        # 获取该小组 & 任务相关的评分记录
        scores = Score.objects.filter(groups=group, tasks=task).prefetch_related("sysusers")

        # 构建返回数据
        score_data = []
        for member in members:
            # 查找该成员的评分记录
            score_entry = scores.filter(sysusers=member).first()
            if score_entry:
                score_data.append({
                    "username": member.username,
                    "negotiate": score_entry.negotiate
                })
            else:
                # 如果该成员未被评分，显示为 0
                score_data.append({
                    "username": member.username,
                    "negotiate": -1
                })

        return JsonResponse(score_data, safe=False)

    except Group.DoesNotExist:
        return JsonResponse({"error": "Group not found"}, status=404)
    except Task.DoesNotExist:
        return JsonResponse({"error": "Task not found"}, status=404)


class UpdateScoreView(APIView):
    """
    根据传入的 task_id 和 sysUserId 查询 Score 记录，
    如果存在则更新各评分项：新分数 = (原分数 + 新传入分数) / 2，
    如果不存在则创建新的评分记录（初始值直接使用传入分数）。

    注意：学生不能给自己评分，这里假设评分记录中 raters 不包含当前学生。
    前端需要传入参数：
      - task_id
      - sysUserId （学生ID）
      - group_id （可选，用于关联小组）
      - 各评分项：quality, engagement, negotiate, on_time, rematch_willingness
    """

    def post(self, request, *args, **kwargs):
        task_id = request.data.get("task_id")
        sysuser_id = request.data.get("sysUserId")
        group_id = request.data.get("group_id")

        # 新评分数据（必须是数值）
        new_quality = request.data.get("quality")
        new_engagement = request.data.get("engagement")
        new_negotiate = request.data.get("negotiate")
        new_on_time = request.data.get("on_time")
        new_rematch_willingness = request.data.get("rematch_willingness")

        # 检查必填参数
        if not task_id or not sysuser_id:
            return Response({"error": "缺少 task_id 或 sysUserId 参数"}, status=status.HTTP_400_BAD_REQUEST)

        # 获取对应的学生和任务对象
        student = get_object_or_404(SysUser, user_id=sysuser_id)
        task_obj = get_object_or_404(Task, id=task_id)

        # 查询当前评分记录：通过关联 task 和 sysUser
        score = Score.objects.filter(tasks=task_obj, sysusers=student).first()

        # 如果不存在，则创建一条新的记录，初始值直接使用传入数据（若某项未传，则设为 0）
        if not score:
            score = Score.objects.create(
                quality=float(new_quality) if new_quality is not None else 0,
                engagement=float(new_engagement) if new_engagement is not None else 80,
                negotiate=float(new_negotiate) if new_negotiate is not None else 80,
                on_time=float(new_on_time) if new_on_time is not None else 100,
                rematch_willingness=float(new_rematch_willingness) if new_rematch_willingness is not None else 80,
                total= 0,
            )
            score.sysusers.add(student)
            score.tasks.add(task_obj)
            if group_id:
                group_obj = get_object_or_404(Group, id=group_id)
                score.groups.add(group_obj)
            score.save()
            return Response({
                "message": "Score created",
                "score": {
                    "quality": score.quality,
                    "engagement": score.engagement,
                    "negotiate": score.negotiate,
                    "on_time": score.on_time,
                    "rematch_willingness": score.rematch_willingness,
                    "total": score.total
                }
            }, status=status.HTTP_201_CREATED)

        # 如果记录存在，则更新（对每个评分项，新值 = (原值 + 新传入值)/2）
        # 只有当新值不为空时才更新
        if new_quality is not None:
            score.quality = (score.quality + float(new_quality)) / 2
        if new_engagement is not None:
            score.engagement = (score.engagement + float(new_engagement)) / 2
        if new_negotiate is not None:
            score.negotiate = (score.negotiate + float(new_negotiate)) / 2
        if new_on_time is not None:
            score.on_time = (score.on_time + float(new_on_time)) / 2
        if new_rematch_willingness is not None:
            score.rematch_willingness = (score.rematch_willingness + float(new_rematch_willingness)) / 2

        score.save()
        return Response({
            "message": "Score updated",
            "score": {
                "quality": score.quality,
                "engagement": score.engagement,
                "negotiate": score.negotiate,
                "on_time": score.on_time,
                "rematch_willingness": score.rematch_willingness,
                "total": score.total
            }
        }, status=status.HTTP_200_OK)


class GetMyScoreView(APIView):
    """
    根据 task_id, group_id 和 sysUserId 查询当前学生的分数记录，
    返回所有评分维度的数据。若不存在则返回提示信息。
    """

    def get(self, request, *args, **kwargs):
        task_id = request.query_params.get("task_id")
        group_id = request.query_params.get("group_id")
        sysUserId = request.query_params.get("sysUserId")
        if not (task_id and group_id and sysUserId):
            return Response({"error": "缺少必要参数"}, status=status.HTTP_400_BAD_REQUEST)

        score = Score.objects.filter(tasks__id=task_id, groups__id=group_id, sysusers__user_id=sysUserId).first()
        if not score:
            return Response({"message": "暂无分数记录"}, status=status.HTTP_404_NOT_FOUND)

        data = {
            "quality": float(score.quality),
            "engagement": float(score.engagement),
            "negotiate": float(score.negotiate),
            "on_time": float(score.on_time),
            "rematch_willingness": float(score.rematch_willingness),
            "created_at": score.created_at,
            "updated_at": score.updated_at,
        }
        return Response({"score": data}, status=status.HTTP_200_OK)

class SubmitPeerReviewView(APIView):
    """
    接收小组互评分数据：
    前端传入参数包括：
      - task_id
      - group_id
      - sysUserId（评分人）
      - reviews: 一个 JSON 对象，键为目标学生 ID，值为包含以下三个评分项的对象：
          { "rematch_willingness": 分数, "engagement": 分数, "negotiate": 分数 }
    对于每个目标学生（排除评分人本人），更新或创建对应的 Score 记录，
    新分数 = (原值 + 新传入分数) / 2（所有数值使用 Decimal 类型进行运算）。
    同时将评分人加入该记录的 raters 字段，防止重复打分。
    """
    def post(self, request, *args, **kwargs):
        data = request.data
        task_id = data.get("task_id")
        group_id = data.get("group_id")
        rater_id = data.get("sysUserId")
        reviews = data.get("reviews")  # 例如 { "101": {"rematch_willingness": 80, "engagement": 85, "negotiate": 90}, ... }
        if not (task_id and group_id and rater_id and reviews):
            return Response({"error": "缺少必要参数"}, status=status.HTTP_400_BAD_REQUEST)

        results = []
        for target_id, review_scores in reviews.items():
            # 排除自己评分
            if str(target_id) == str(rater_id):
                continue

            # 查询对应的评分记录
            score = Score.objects.filter(tasks__id=task_id, groups__id=group_id, sysusers__user_id=target_id).first()
            try:
                # 将传入的评分转换为 Decimal
                new_engagement = Decimal(str(review_scores.get("engagement", 85)))
                new_negotiate = Decimal(str(review_scores.get("negotiate", 85)))
                new_rematch = Decimal(str(review_scores.get("rematch_willingness", 85)))
            except (InvalidOperation, TypeError) as e:
                return Response({"error": "传入的评分数值格式不正确", "details": str(e)},
                                status=status.HTTP_400_BAD_REQUEST)

            if not score:
                # 创建新记录，初始值使用传入数值（质量分默认为 0，准时分默认为 100）
                score = Score.objects.create(
                    quality=Decimal("0"),
                    engagement=new_engagement,
                    negotiate=new_negotiate,
                    on_time=Decimal("100"),
                    rematch_willingness=new_rematch,
                    total=Decimal("0")
                )
                target_user = get_object_or_404(SysUser, user_id=target_id)
                score.sysusers.add(target_user)
                task_obj = get_object_or_404(Task, id=task_id)
                score.tasks.add(task_obj)
                group_obj = get_object_or_404(Group, id=group_id)
                score.groups.add(group_obj)
                score.save()
            else:
                # 更新记录：新值 = (原值 + 新传入值) / 2
                score.engagement = (score.engagement + new_engagement) / Decimal("2")
                score.negotiate = (score.negotiate + new_negotiate) / Decimal("2")
                score.rematch_willingness = (score.rematch_willingness + new_rematch) / Decimal("2")
                score.save()
            # 添加评分人到 raters（避免重复打分）
            rater = get_object_or_404(SysUser, user_id=rater_id)
            if not score.raters.filter(user_id=rater_id).exists():
                score.raters.add(rater)
            results.append({
                "target_id": target_id,
                "engagement": float(score.engagement),
                "negotiate": float(score.negotiate),
                "rematch_willingness": float(score.rematch_willingness)
            })

        return Response({"message": "互评分提交成功", "results": results}, status=status.HTTP_200_OK)


class SubmitAppealView(APIView):
    """
    学生提交申诉接口
    前端传入参数：
      - task_id
      - group_id
      - sysUserId
      - reason（申诉理由）
    创建一条 Appeal 记录，并返回成功提示。
    """

    def post(self, request, *args, **kwargs):
        task_id = request.data.get("task_id")
        group_id = request.data.get("group_id")
        sysUserId = request.data.get("sysUserId")
        reason = request.data.get("reason")
        if not (task_id and group_id and sysUserId and reason):
            return Response({"error": "缺少必要参数"}, status=status.HTTP_400_BAD_REQUEST)

        task_obj = get_object_or_404(Task, id=task_id)
        group_obj = get_object_or_404(Group, id=group_id)
        sysuser_obj = get_object_or_404(SysUser, user_id=sysUserId)

        appeal = Appeal.objects.create(
            task=task_obj,
            group=group_obj,
            sysuser=sysuser_obj,
            reason=reason
        )

        return Response({
            "message": "申诉提交成功",
            "appeal_id": appeal.id
        }, status=status.HTTP_201_CREATED)


class Score_GetGroupMembersView(APIView):
    """
    根据传入的 task_id 和 group_id 返回对应小组的成员名单
    示例请求：GET /api/group-members/?task_id=7&group_id=2
    返回示例：
      [
        { "user_id": 101, "username": "张三" },
        { "user_id": 102, "username": "李四" },
        ...
      ]
    """

    def get(self, request, *args, **kwargs):
        task_id = request.query_params.get("task_id")
        group_id = request.query_params.get("group_id")
        if not task_id or not group_id:
            return Response(
                {"error": "缺少 task_id 或 group_id 参数"},
                status=status.HTTP_400_BAD_REQUEST
            )

        # 获取 Group 对象，确保该组隶属于传入的任务 task_id
        group = get_object_or_404(Group, id=group_id, group_task__id=task_id)

        # 获取成员列表
        members = group.members.all()
        member_list = [
            {"user_id": member.user_id, "username": member.username}
            for member in members
        ]
        return Response(member_list, status=status.HTTP_200_OK)


import re
import json
import logging
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from django.shortcuts import get_object_or_404
from spark.models import Task, Group, SysUser, ReferencePosition

logger = logging.getLogger(__name__)

@api_view(['POST'])
def generate_positions_and_survey(request):
    user_id = request.data.get("user_id")
    group_id = request.data.get("group_id")
    task_id = request.data.get("task_id")
    theme = request.data.get("theme", "")

    if not (user_id and group_id and task_id):
        return Response({"error": "缺少 user_id、group_id 或 task_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

    task = get_object_or_404(Task, id=task_id)
    group = get_object_or_404(Group, id=group_id, group_task=task)
    members = group.members.all()
    member_count = members.count()
    member_list = []
    for m in members:
        member_list.append({
            "user_id": m.user_id,
            "username": m.username,
            "ability": m.ability,
            "enthusiasm": m.enthusiasm,
            "communication": m.communication,
            "popularity": m.popularity,
            "credit": m.credit,
            "times": m.times,
        })

    task_info = {
        "title": task.title,
        "description": task.description,
        "deadline": task.deadline.strftime("%Y-%m-%d %H:%M:%S") if task.deadline else "",
        "scoring_criteria": task.scoring_criteria,
        "status": task.status,
    }

    prompt = f"""
【任务信息】
标题：{task_info['title']}
描述：{task_info['description']}
截止时间：{task_info['deadline']}
评分标准：{task_info['scoring_criteria']}
任务状态：{task_info['status']}

【小组信息】
小组名称：{group.group_name}
小组成员数：{member_count}
成员及其能力：
{json.dumps(member_list, ensure_ascii=False, indent=4)}

【感兴趣的主题】
{theme}

由于已经存在组长，所以不需要项目负责人职位。请注意，你可以将多个必要任务分配给同一个职位，但职位总数不得超过小组成员数。请根据以上信息生成两部分输出：
1. 参考职位列表（JSON格式），例如：
[
  {{"职位": "xxx", "人数": 1, "描述": "xxx"}},
  ...
]

2. 兴趣调查问卷（文本格式），格式如下：
【示例】关于本次小组作业您的兴趣任务的调查问卷
1.您的姓名是？

2.您擅长的技能是 [排序题]
编程
设计
文案
其他

3.请对上面列出的参考职位的感兴趣程度作个评价 [矩阵题]
很不感兴趣 不感兴趣 一般 感兴趣 很感兴趣
前端开发
后端开发
测试
课堂展示

4.您对本次小组作业的最大期望是什么？
A.获得高分
B.学到新知识
C.锻炼团队协作
D.能过就行

5.您愿意每周为本次小组作业付出多少时间？

6.您对本次小组作业有什么额外需求吗？

请注意：
- 仅输出上述两部分内容，第一部分为 JSON 数据，第二部分为纯文本，不要额外添加其他文字。
"""

    try:
        logger.info("开始调用 DeepSeek 分析任务信息生成参考职位和问卷...")
        completion = client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "You are a fair performance evaluator."},
                {"role": "user", "content": prompt},
            ],
            stream=False
        )
        analysis_raw = completion.choices[0].message.content
        logger.info("DeepSeek 原始返回内容: %s", analysis_raw)

        # 利用正则提取 JSON 部分（即第一个 ```json ... ``` 块）
        json_match = re.search(r'```json\s*(.*?)\s*```', analysis_raw, re.DOTALL)
        if not json_match:
            raise ValueError("未能提取到 JSON 部分")
        json_str = json_match.group(1).strip()

        # 剩余部分作为问卷文本
        survey_text = analysis_raw.replace(json_match.group(0), "").strip()

        # 解析 JSON 部分
        positions_json = json.loads(json_str)
    except Exception as e:
        logger.error("调用大模型或解析返回结果失败：", exc_info=True)
        return Response({"error": "调用大模型或解析返回结果失败", "details": str(e)},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    # 清空旧的参考职位记录，并保存新职位列表
    ReferencePosition.objects.filter(task=task, group=group).delete()
    for pos in positions_json:
        ReferencePosition.objects.create(
            task=task,
            group=group,
            title=pos["职位"],
            needed_count=pos["人数"],
            description=pos["描述"]
        )

    return Response({
        "positions": positions_json,
        "survey": survey_text
    }, status=status.HTTP_200_OK)


@api_view(['GET'])
def get_reference_positions(request):
    """
    GET /api/reference-positions/?task_id=...&group_id=...
    返回该任务和小组的参考职位列表。
    返回示例：
    {
      "positions": [
         {"职位": "前端开发", "人数": 2, "描述": "负责页面UI..."},
         {"职位": "后端开发", "人数": 2, "描述": "负责数据库..."}
      ]
    }
    """
    task_id = request.query_params.get("task_id")
    group_id = request.query_params.get("group_id")
    if not (task_id and group_id):
        return Response({"error": "缺少 task_id 或 group_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

    # 验证任务和小组
    task = get_object_or_404(Task, id=task_id)
    group = get_object_or_404(Group, id=group_id, group_task=task)

    positions = ReferencePosition.objects.filter(task=task, group=group)
    data = []
    for pos in positions:
        data.append({
            "职位": pos.title,
            "人数": pos.needed_count,
            "描述": pos.description,
        })
    return Response({"positions": data}, status=status.HTTP_200_OK)

@api_view(['POST'])
def allocate_subtasks(request):
    """
    POST /api/allocate-subtasks/
    请求参数：
    {
       "task_id": 1,
       "group_id": 2,
       "csv_content": "上传的CSV内容字符串"
    }
    解析 CSV 内容、查询参考职位列表，并构造大模型 Prompt，
    调用大模型生成每个成员的最佳职位分配推荐，返回 JSON 格式的分配结果。
    """
    task_id = request.data.get("task_id")
    group_id = request.data.get("group_id")
    csv_content = request.data.get("csv_content")

    if not (task_id and group_id and csv_content):
        return Response({"error": "缺少 task_id、group_id 或 csv_content 参数"}, status=status.HTTP_400_BAD_REQUEST)

    # 1. 查询任务和小组
    task = get_object_or_404(Task, id=task_id)
    group = get_object_or_404(Group, id=group_id, group_task=task)
    # 2. 获取参考职位列表
    positions = ReferencePosition.objects.filter(task=task, group=group)
    positions_list = []
    for pos in positions:
        positions_list.append({
            "职位": pos.title,
            "人数": pos.needed_count,
            "描述": pos.description,
        })

    # 3. 构造 Prompt 给大模型
    prompt = f"""
根据以下所有成员的回答（CSV 格式），注意，之后输出的姓名应当与回答中的姓名相符：
{csv_content}

以及以下可用的职位列表和每个职位所需的人数：
{json.dumps(positions_list, ensure_ascii=False, indent=4)}
本组成员包括：
{group.members.all().values_list("username", flat=True)}

请统筹考虑所有成员的需求和职位的人数限制，为每个成员分配最合适的职位。
请确保每个职位分配的人数不超过所需人数。
请输出所有成员的分配结果，格式为 JSON：
[
    {{"姓名": "成员姓名", "推荐职位": "职位名称", "推荐理由": "理由描述", "工作内容以及时间规划": "初步时间规划"}}
]
仅输出 JSON 数据，不要添加额外文字。
"""

    # 4. 调用大模型接口
    try:
        completion = client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "system", "content": "You are an expert in task allocation."},
                {"role": "user", "content": prompt},
            ],
            stream=False
        )
        analysis_raw = completion.choices[0].message.content
        # 去除多余标记
        analysis_str = analysis_raw.replace("```json", "").replace("```", "").strip()
        logger.info(f"DeepSeek 返回原始结果: {analysis_str}")
        # 解析返回的 JSON
        allocation_result = json.loads(analysis_str)
    except Exception as e:
        logger.error("调用大模型失败：", exc_info=True)
        return Response({"error": "调用大模型失败", "details": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    # 5. 返回分工推荐结果给前端
    return Response({"analysis": allocation_result}, status=status.HTTP_200_OK)


class GetTeacherAppealsView(APIView):
    def get(self, request, *args, **kwargs):
        teacher_id = request.query_params.get("teacher_id")
        if not teacher_id:
            return Response({"error": "缺少 teacher_id 参数"}, status=status.HTTP_400_BAD_REQUEST)
        # 查询教师名下所有任务
        tasks = Task.objects.filter(teacher__user_id=teacher_id)
        # 查询这些任务下的所有申诉
        appeals = Appeal.objects.filter(task__in=tasks).select_related('task', 'group', 'sysuser')
        appeals_list = []
        for a in appeals:
            appeals_list.append({
                "id": a.id,
                "task_id": a.task.id,
                "task_title": a.task.title,
                "group_name": a.group.group_name,
                "student": {
                    "user_id": a.sysuser.user_id,
                    "username": a.sysuser.username
                },
                "reason": a.reason,
                "created_at": a.created_at,
                "status": a.status,
            })
        return Response({"appeals": appeals_list}, status=status.HTTP_200_OK)

class UpdateAppealStatusView(APIView):
    def post(self, request, *args, **kwargs):
        appeal_id = request.data.get("appeal_id")
        decision = request.data.get("decision")
        if not (appeal_id and decision):
            return Response({"error": "缺少 appeal_id 或 decision 参数"}, status=status.HTTP_400_BAD_REQUEST)
        appeal = get_object_or_404(Appeal, id=appeal_id)
        # 可增加判断，确保 decision 合法
        if decision not in ["approved", "rejected"]:
            return Response({"error": "decision 参数不合法"}, status=status.HTTP_400_BAD_REQUEST)
        appeal.status = decision
        appeal.save()
        return Response({"message": "申诉状态更新成功"}, status=status.HTTP_200_OK)


class GetProgressTrackingView(APIView):
    """
    根据传入的 teacher_id 查询该教师所有状态为 working 的任务，
    然后对于每个任务的每个小组，统计该组 subtask 数量和状态分布，
    返回每个组的：
      - 总 subtask 数量
      - in_progress 数量
      - on_time 数量
      - in_progress 中评论以“不通过”开头的数量
      - late 数量
      - 组长信息（leader_id、leader 的 username 等）
      - 小组 id
    """

    def get(self, request, *args, **kwargs):
        teacher_id = request.query_params.get("teacher_id")
        if not teacher_id:
            return Response({"error": "缺少 teacher_id 参数"}, status=status.HTTP_400_BAD_REQUEST)

        # 查询该教师状态为 working 的任务
        tasks = Task.objects.filter(Q(teacher__user_id=teacher_id) & (Q(status="scoring") | Q(status="working")))
        result = []
        for task in tasks:
            # 遍历该任务下的每个小组
            groups = task.groups.all()
            for group in groups:
                # 对该组的 Subtask 进行统计
                total_count = Subtask.objects.filter(group_id=group).count()
                in_progress_count = Subtask.objects.filter(group_id=group, status="in_progress").count()
                on_time_count = Subtask.objects.filter(group_id=group, status="on_time").count()
                not_approved_in_progress = Subtask.objects.filter(
                    group_id=group,
                    status="in_progress",
                    comments__startswith="不通过"
                ).count()
                late_count = Subtask.objects.filter(group_id=group, status="late").count()

                result.append({
                    "task_id": task.id,
                    "task_title": task.title,
                    "group_id": group.id,
                    "group_name": group.group_name,
                    "leader": {
                        "user_id": group.leader_id.user_id,
                        "username": group.leader_id.username,
                    },
                    "total_subtasks": total_count,
                    "in_progress": in_progress_count,
                    "on_time": on_time_count,
                    "in_progress_not_approved": not_approved_in_progress,
                    "late": late_count,
                })
        return Response({"progress": result}, status=status.HTTP_200_OK)

class GetTeacherScoresView(APIView):
    """
    根据 teacher_id 获取状态为 scoring 的任务下所有学生的评分记录
    """
    def get(self, request, *args, **kwargs):
        teacher_id = request.query_params.get("teacher_id")
        if not teacher_id:
            return Response({"error": "缺少 teacher_id 参数"}, status=status.HTTP_400_BAD_REQUEST)
        tasks = Task.objects.filter(teacher__user_id=teacher_id, status="scoring")
        result = []
        for task in tasks:
            # 假设每个任务中参与的学生信息可以从 Score 表中找到
            scores = Score.objects.filter(tasks=task).distinct()
            for score in scores:
                # 这里假设每个 Score 记录仅关联一个学生（通过 sysusers 字段）
                student = score.sysusers.first()
                result.append({
                    "task_id": task.id,
                    "task_title": task.title,
                    "student": {"user_id": student.user_id, "username": student.username} if student else {},
                    "quality": float(score.quality),
                    "engagement": float(score.engagement),
                    "negotiate": float(score.negotiate),
                    "on_time": float(score.on_time),
                    "rematch_willingness": float(score.rematch_willingness),
                    "total": float(score.total)
                })
        return Response({"scores": result}, status=status.HTTP_200_OK)


class FinalizeTaskScoresView(APIView):
    """
    教师提交评分权重后，计算每个任务下所有学生的总分并更新任务状态为 finished，
    同时更新每个学生的能力字段。
    前端提交参数示例：
    {
       "task_id": 7,
       "weights": {
          "quality": 0.4,
          "engagement": 0.2,
          "negotiate": 0.2,
          "on_time": 0.1,
          "rematch_willingness": 0.1
       },
       "quality_updates": { "10": 90, "11": 85 }  // 键为学生ID，值为修改后的 quality 分数
    }
    """

    def post(self, request, *args, **kwargs):
        task_id = request.data.get("task_id")
        weights = request.data.get("weights")
        quality_updates = request.data.get("quality_updates", {})
        if not (task_id and weights):
            return Response({"error": "缺少 task_id 或 weights 参数"}, status=status.HTTP_400_BAD_REQUEST)
        task = get_object_or_404(Task, id=task_id, status="scoring")

        # 遍历该任务下所有 Score 记录
        scores = Score.objects.filter(tasks=task).distinct()
        for score in scores:
            # 假设每个 Score 记录关联一个学生
            student = score.sysusers.first()
            if not student:
                continue

            # 如果前端传入了修改后的 quality 分数，则更新 score.quality
            if quality_updates.get(str(student.user_id)) is not None:
                new_quality = Decimal(str(quality_updates[str(student.user_id)]))
                score.quality = new_quality

            # 调整 on_time 分数：扣除每个 in_progress subtask扣7分，每个 late subtask扣5分
            subtasks = Subtask.objects.filter(task=task, assigned_to=student)
            in_progress_count = subtasks.filter(status="in_progress").count()
            late_count = subtasks.filter(status="late").count()
            deduction = Decimal(7 * in_progress_count + 5 * late_count)
            new_on_time = score.on_time - deduction
            if new_on_time < 0:
                new_on_time = Decimal(0)
            score.on_time = new_on_time.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

            # 根据权重计算新的总分
            w_quality = Decimal(str(weights.get("quality", 0)))
            w_engagement = Decimal(str(weights.get("engagement", 0)))
            w_negotiate = Decimal(str(weights.get("negotiate", 0)))
            w_on_time = Decimal(str(weights.get("on_time", 0)))
            w_rematch = Decimal(str(weights.get("rematch_willingness", 0)))

            total = (
                    w_quality * score.quality +
                    w_engagement * score.engagement +
                    w_negotiate * score.negotiate +
                    w_on_time * score.on_time +
                    w_rematch * score.rematch_willingness
            )
            score.total = total.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
            score.save()

            # 更新学生能力：times 为学生已完成任务次数
            times = Decimal(student.times)
            student.ability = ((Decimal(student.ability) * times + score.quality) / (times + 1)).quantize(
                Decimal("0.01"), rounding=ROUND_HALF_UP)
            student.enthusiasm = ((Decimal(student.enthusiasm) * times + score.engagement) / (times + 1)).quantize(
                Decimal("0.01"), rounding=ROUND_HALF_UP)
            student.communication = ((Decimal(student.communication) * times + score.negotiate) / (times + 1)).quantize(
                Decimal("0.01"), rounding=ROUND_HALF_UP)
            student.popularity = (
                        (Decimal(student.popularity) * times + score.rematch_willingness) / (times + 1)).quantize(
                Decimal("0.01"), rounding=ROUND_HALF_UP)
            student.credit = ((Decimal(student.credit) * times + score.on_time) / (times + 1)).quantize(Decimal("0.01"),
                                                                                                        rounding=ROUND_HALF_UP)
            student.times += 1
            student.save()

        # 更新任务状态为 finished
        task.status = "finished"
        print(task.status)
        task.save()

        return Response({"message": "评分计算完成，任务状态已更新为 finished"}, status=status.HTTP_200_OK)

class GetFinishedTasksForTeacherView(APIView):
    """
    根据传入的 teacher_id 查询该教师所有状态为 finished 的任务
    """
    def get(self, request, *args, **kwargs):
        teacher_id = request.query_params.get("teacher_id")
        if not teacher_id:
            return Response({"error": "缺少 teacher_id 参数"}, status=status.HTTP_400_BAD_REQUEST)
        tasks = Task.objects.filter(teacher__user_id=teacher_id, status="finished")
        tasks_list = [
            {"id": task.id, "title": task.title, "description": task.description}
            for task in tasks
        ]
        return Response({"finished_tasks": tasks_list}, status=status.HTTP_200_OK)


class GetTaskAnalysisDataView(APIView):
    """
    根据任务 ID 获取该任务的详细数据：
      1. 学生评分数据（Score 表）
      2. Subtask 完成情况统计
      3. 小组分布信息（组长、组员名单、成员数）
      4. 任务基本信息（标题、描述、评分标准、截止时间等）
    """

    def get(self, request, *args, **kwargs):
        task_id = request.query_params.get("task_id")
        if not task_id:
            return Response({"error": "缺少 task_id 参数"}, status=status.HTTP_400_BAD_REQUEST)
        task = get_object_or_404(Task, id=task_id)

        # 获取评分数据（假设 Score 与 SysUser 多对多，每个 Score 记录关联一个学生）
        scores = Score.objects.filter(tasks=task).distinct()
        scores_list = []
        for score in scores:
            student = score.sysusers.first()
            if student:
                scores_list.append({
                    "student_id": student.user_id,
                    "username": student.username,
                    "quality": float(score.quality),
                    "engagement": float(score.engagement),
                    "negotiate": float(score.negotiate),
                    "on_time": float(score.on_time),
                    "rematch_willingness": float(score.rematch_willingness),
                    "total": float(score.total)
                })

        # 统计 Subtask 完成情况
        subtasks = Subtask.objects.filter(task=task)
        subtask_stats = {
            "total": subtasks.count(),
            "in_progress": subtasks.filter(status="in_progress").count(),
            "on_time": subtasks.filter(status="on_time").count(),
            "late": subtasks.filter(status="late").count(),
        }

        # 小组信息：遍历 task.groups
        groups = task.groups.all()
        group_list = []
        for group in groups:
            members = group.members.all()
            group_list.append({
                "group_id": group.id,
                "group_name": group.group_name,
                "leader": {
                    "user_id": group.leader_id.user_id,
                    "username": group.leader_id.username,
                },
                "member_count": members.count(),
                "members": [{"user_id": m.user_id, "username": m.username} for m in members]
            })

        result = {
            "task": {
                "id": task.id,
                "title": task.title,
                "description": task.description,
                "scoring_criteria": task.scoring_criteria,
                "deadline": task.deadline.strftime("%Y-%m-%d %H:%M:%S") if task.deadline else ""
            },
            "scores": scores_list,
            "subtask_stats": subtask_stats,
            "groups": group_list
        }
        print(result)
        return Response(result, status=status.HTTP_200_OK)


logger = logging.getLogger(__name__)


class AnalyzeTaskQualityView(APIView):
    """
    接收前端传来的任务分析数据，构造 Prompt 调用大模型，
    返回分析结果和建议。
    前端提交参数示例：
    {
      "task_data": { ... }   # 包含任务基本信息、评分数据、subtask统计，可能不包含小组信息
    }
    如果 task_data 中没有 groups 字段，则自动根据 task_id 查询小组信息，并加入到 task_data 中
    """

    def post(self, request, *args, **kwargs):
        task_data = request.data.get("task_data")
        if not task_data:
            return Response({"error": "缺少 task_data 参数"}, status=status.HTTP_400_BAD_REQUEST)

        # 自动查询小组信息：从 task_data 获取任务 id
        task_id = task_data.get("task", {}).get("id")
        if task_id:
            groups_qs = Group.objects.filter(group_task__id=task_id)
            groups_list = []
            for group in groups_qs:
                leader = group.leader_id
                members = group.members.all()
                groups_list.append({
                    "group_id": group.id,
                    "group_name": group.group_name,
                    "leader": {
                        "user_id": leader.user_id,
                        "username": leader.username
                    } if leader else None,
                    "members": [{"user_id": m.user_id, "username": m.username} for m in members]
                })
            task_data['groups'] = groups_list
        else:
            task_data['groups'] = []

        # 构造 Prompt 给大模型
        prompt = f"""
请根据以下信息生成详细的任务分析报告，必须严格按照指定的 JSON 格式输出，不要添加任何额外说明：

【任务信息】
标题：{task_data['task']['title']}
描述：{task_data['task']['description']}
截止时间：{task_data['task']['deadline']}
评分标准：{task_data['task']['scoring_criteria']}

【学生评分数据】
{json.dumps(task_data['scores'], ensure_ascii=False, indent=4)}

【子任务完成情况】
{json.dumps(task_data['subtask_stats'], ensure_ascii=False, indent=4)}

【小组信息】
{json.dumps(task_data['groups'], ensure_ascii=False, indent=4)}

请输出以下格式的 JSON：
{{
    "analysis": {{
        "task_completion": {{
            "total": 总任务数,
            "in_progress": 进行中数量,
            "on_time": 按时完成数量,
            "late": 逾期未交数量
        }},
        "student_performance": [
            {{
                "username": "学生姓名",
                "quality": 任务质量分(0-100),
                "engagement": 参与积极性(0-100),
                "negotiate": 协商分(0-100),
                "on_time": 准时完成分(0-100),
                "rematch_willingness": 重组意愿(0-100),
                "total": 总分(0-100),
                "performance": "优秀/良好/一般"
            }}
        ],
        "excellent_student": "优秀学生的表现分析",
        "focus_student": "需要关注的学生分析",
        "student_details": [
            {{
                "username": "学生姓名",
                "优点": "该学生的优点分析",
                "不足": "该学生的不足分析"
            }}
        ],
        "group_performance": {{
            "group_name": "小组名称",
            "overall_performance": "优秀/良好/一般",
            "leader_performance": "组长表现评价",
            "members_performance": "成员整体表现评价"
        }},
        "teaching_quality": "整体教学质量评价"
    }},
    "suggestions": {{
        "教师建议": {{
            "大作业内容": "1. xxx\\n2. xxx\\n3. xxx",
            "学生指导": "1. xxx\\n2. xxx\\n3. xxx"
        }}
    }}
}}
"""
        try:
            logger.info("开始调用大模型进行教学质量分析...")
            completion = client.chat.completions.create(
                model="deepseek-chat",
                messages=[
                    {"role": "system", "content": "You are a fair performance evaluator."},
                    {"role": "user", "content": prompt},
                ],
                stream=False
            )
            analysis_raw = completion.choices[0].message.content
            logger.info("大模型原始返回内容: %s", analysis_raw)

            # 清洗返回的文本：去除前后的 ```json 和 ``` 包装
            clean_analysis = analysis_raw.strip()
            if clean_analysis.startswith("```json"):
                clean_analysis = clean_analysis[len("```json"):].strip()
            if clean_analysis.endswith("```"):
                clean_analysis = clean_analysis[:-3].strip()

            # 解析 JSON
            analysis_result = json.loads(clean_analysis)

            # 确保返回的数据结构完整
            if "analysis" not in analysis_result:
                analysis_result = {"analysis": analysis_result}

            # 如果没有 suggestions 字段，添加空的 suggestions
            if "suggestions" not in analysis_result:
                analysis_result["suggestions"] = {
                    "教师建议": {
                        "大作业内容": "",
                        "学生指导": ""
                    }
                }

            return Response(analysis_result, status=status.HTTP_200_OK)

        except json.JSONDecodeError as e:
            logger.error("JSON 解析失败：%s", str(e))
            return Response(
                {"error": "解析大模型返回结果失败", "details": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
        except Exception as e:
            logger.error("调用大模型失败：", exc_info=True)
            return Response(
                {"error": "调用大模型失败", "details": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

class CreateForumPostView(APIView):
    def post(self, request, *args, **kwargs):
        data = request.data.copy()
        # 如果当前用户未认证，则尝试从数据中读取 author_id
        if request.user.is_anonymous:
            author_id = data.get("author_id")
            if not author_id:
                return Response(
                    {"success": False, "errors": {"author": ["未登录时必须传入 author_id"]}},
                    status=status.HTTP_400_BAD_REQUEST
                )
            try:
                author_instance = SysUser.objects.get(user_id=author_id)
            except SysUser.DoesNotExist:
                return Response(
                    {"success": False, "errors": {"author": ["指定的用户不存在"]}},
                    status=status.HTTP_400_BAD_REQUEST
                )
        else:
            author_instance = request.user

        serializer = ForumPostSerializer(data=data)
        if serializer.is_valid():
            serializer.save(author=author_instance)
            return Response(
                {"success": True, "post": serializer.data},
                status=status.HTTP_201_CREATED
            )
        return Response(
            {"success": False, "errors": serializer.errors},
            status=status.HTTP_400_BAD_REQUEST
        )
class ForumPostsListView(APIView):
    def get(self, request, *args, **kwargs):
        category = request.query_params.get("category", "publish")
        posts = ForumPost.objects.filter(category=category).order_by("-created_at")
        serializer = ForumPostSerializer(posts, many=True)
        return Response({"success": True, "posts": serializer.data}, status=status.HTTP_200_OK)

class ForumPostDetailView(APIView):
    def get(self, request, post_id, *args, **kwargs):
        post = get_object_or_404(ForumPost, id=post_id)
        serializer = ForumPostSerializer(post)
        return Response({"success": True, "post": serializer.data}, status=status.HTTP_200_OK)